package com.kingmed.kmss.bpmn.flow.command;

import static org.flowable.common.engine.api.query.Query.NullHandlingOnOrder.NULLS_LAST;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.flowable.common.engine.impl.db.ListQueryParameterObject;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.ManagementService;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.kingmed.kmss.common.bo.bpmn.CommentBO;
import com.kingmed.kmss.common.bo.bpmn.TaskBO;
import com.kingmed.kmss.common.qc.bpmn.TaskQueryCondition;
import com.kingmed.kmss.common.utils.BeanCopyUtils;

import lombok.extern.slf4j.Slf4j;


/**
 * 直接通过自定义sql查询flowable数据库，调用mapper的sql
 */
@Slf4j
@Service
public class TaskSqlCommand {

    @Autowired
    ManagementService managementService;

    public TaskSqlCommand(ManagementService managementService) {
        super();
        this.managementService = managementService;
        //执行数据库操作
    }

    /**
     * @param taskId
     * @return
     */
    public TaskBO findTaskById(String taskId) {

        TaskBO resultSet = managementService.executeCommand(new Command<TaskBO>() {
            @Override
            public TaskBO execute(CommandContext commandContext) {
                return (TaskBO) CommandContextUtil.getDbSqlSession().selectOne("selectTaskComboById", taskId);
            }
        });

        log.info(" findTaskById() result is: {}", resultSet);
        return resultSet;
    }

    /**
     * @param qryCond
     * @return
     */
    public List<TaskBO> findTaskByConditionWithoutGroup(TaskQueryCondition qryCond) {

        Map<String, Object> paramMap = new HashMap<>();

        BeanCopyUtils.copyToMap(qryCond);

        List<TaskBO> resultSet = managementService.executeCommand(new Command<List<TaskBO>>() {
            @SuppressWarnings("unchecked")
            @Override
            public List<TaskBO> execute(CommandContext commandContext) {
                return (List<TaskBO>) CommandContextUtil.getDbSqlSession()
                        .selectListWithRawParameter("selectTaskComboByConditionWithoutGroup", paramMap);
            }
        });

        if (resultSet != null)
            log.info("Sql select result count is: {}", resultSet.size());
        else
            log.info(" No matched result.");
        log.info(" findTaskByConditionWithoutGroup() result is: {}", resultSet);
        return resultSet;
    }

    /**
     * @param qryCond
     * @return
     */
    public List<TaskBO> findTaskByCondition(TaskQueryCondition qryCond) {

        Map<String, Object> paramMap = new HashMap<>();

        BeanCopyUtils.copyToMap(qryCond);

        List<TaskBO> resultSet = managementService.executeCommand(new Command<List<TaskBO>>() {
            @SuppressWarnings("unchecked")
            @Override
            public List<TaskBO> execute(CommandContext commandContext) {
                return (List<TaskBO>) CommandContextUtil.getDbSqlSession()
                        .selectListWithRawParameter("selectTaskComboByCondition", paramMap);
            }
        });

        if (resultSet != null)
            log.info("Sql select result count is: {}", resultSet.size());
        else
            log.info(" No matched result.");
        log.info(" findTaskByCondition() result is: {}", resultSet);
        return resultSet;
    }

    /**
     * @param qryCond
     * @return
     */
    public List<TaskBO> findMyTask(TaskQueryCondition qryCond) {

        Map<String, Object> paramMap = new HashMap<>();
        qryCond.setIdentityType("candidate");

        BeanCopyUtils.copyToMap(qryCond);

        List<TaskBO> resultSet = managementService.executeCommand(new Command<List<TaskBO>>() {
            @SuppressWarnings("unchecked")
            @Override
            public List<TaskBO> execute(CommandContext commandContext) {
                return (List<TaskBO>) CommandContextUtil.getDbSqlSession().selectList("selectMyTaskCount",
                        paramMap);
            }
        });

        if (resultSet != null)
            log.info("Sql findMyTask result count is: {}", resultSet.size());
        else
            log.info(" No matched result.");
        log.info(" findMyTask() result is: {}", resultSet);
        return resultSet;
    }

    /**
     * 分页
     *
     * @param qryCond
     * @param first
     * @param max
     * @return
     */
    public List<TaskBO> findMyTaskPage(TaskQueryCondition qryCond, int first, int max) {

        Map<String, Object> paramMap = new HashMap<>();
        qryCond.setIdentityType("candidate");

        BeanCopyUtils.copyToMap(qryCond);

        List<TaskBO> resultSet = managementService.executeCommand(new Command<List<TaskBO>>() {
            @SuppressWarnings("unchecked")
            @Override
            public List<TaskBO> execute(CommandContext commandContext) {
                ListQueryParameterObject object = new ListQueryParameterObject(paramMap, first, max);
                object.addOrder("startTime", "asc"
                        , NULLS_LAST);
                return (List<TaskBO>) CommandContextUtil.getDbSqlSession().selectList("selectMyTask",
                        object);
            }
        });

        if (resultSet != null)
            log.info("Sql findMyTaskPage result count is: {}", resultSet.size());
        else
            log.info(" No matched result.");
        log.info(" findMyTaskPage() result is: {}", resultSet);
        return resultSet;
    }

    public List<CommentBO> findCommentsByCondition(CommentBO qryCond) {

        Map<String, Object> paramMap = new HashMap<>();

        BeanCopyUtils.copyToMap(qryCond);

        List<CommentBO> resultSet = managementService.executeCommand(new Command<List<CommentBO>>() {
            @SuppressWarnings("unchecked")
            @Override
            public List<CommentBO> execute(CommandContext commandContext) {
                return (List<CommentBO>) CommandContextUtil.getDbSqlSession()
                        .selectListWithRawParameter("selectTaskCommentsByCondition", paramMap);
            }
        });

        if (resultSet != null)
            log.info("Sql select result count is: {}", resultSet.size());
        else
            log.info(" No matched result.");
        log.info(" findTaskCommentsByCondition() result is: {}", resultSet);
        return resultSet;
    }

    public CommentBO findCommentByTaskAndUserId(String taskId, String userId) {
        CommentBO commentBO = new CommentBO();
        commentBO.setTaskId(taskId);
        commentBO.setUserId(userId);

        List<CommentBO> result = this.findCommentsByCondition(commentBO);
        if (result != null && result.size() > 0)
            return result.get(0);
        else
            return null;
    }

    public List<CommentBO> findCommentByTaskId(String taskId) {
        CommentBO commentBO = new CommentBO();
        commentBO.setTaskId(taskId);
        List<CommentBO> result = this.findCommentsByCondition(commentBO);
        return result;
    }

    public List<CommentBO> findCommentByProcessInstanceId(String processInstanceId) {
        CommentBO commentBO = new CommentBO();
        commentBO.setProcessInstanceId(processInstanceId);

        List<CommentBO> result = this.findCommentsByCondition(commentBO);
        return result;
    }

}
